package com.green.dao;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;

import com.green.model.manage.Person;


public class MyBatisXMLDaoImpl {


	private static String tableName="T_green_ErpPackageOrder";//表名
	private static String projectName="green";//项目名称
	@SuppressWarnings("rawtypes")
	private static Class className= Person.class;


	
	public static MyBatisXMLDaoImpl object=new MyBatisXMLDaoImpl();
	private static String modelName="";
	public static void main(String[] args) throws SQLException {
		modelName=className.getSimpleName();
		ResultSet rs=object.getResult();
		 object.grenerateResultMap(rs);
		 object.grenerateGetModelById();
		 object.grenerateInsertXML(rs);
		 object.grenerateUpdateXML(rs);
		 object.grenerateDeleteXml();
		 // object.grenerateCreateTableSql();

	}

	/**
	 * 根据字段属性取类属性
	 * @param column
	 * @return
	 */
	private Field getPropertyByColumn(String column){
		Field[] ary=className.getDeclaredFields();
		String str="";
		Field resultField=null;
		if(column.endsWith("ID")&& column.startsWith("FK")){
			str=column.substring(2);
			str=str.substring(0,str.length()-2);
		}else if(column.startsWith("F")){
			str=column.substring(1);
		}
		for(int i=0;i<ary.length;i++){
			Field field=ary[i];
			if(str.equalsIgnoreCase(field.getName())){
				resultField=field;
				break;
			}
		}
		return resultField;
	}
	/**
	 * 生成ResultMap
	 * @param rs
	 * @throws SQLException
	 */
	private void grenerateResultMap(ResultSet rs) throws SQLException{
		StringBuilder buf=new StringBuilder();
		//buf.append("<resultMap id="customerResult" type="com.shihua.model.broker.Customer">");
		buf.append("<resultMap id=\"").append(modelName).append("Result\"").append(" type=\"")
			.append(className.getName()).append("\" >").append("\n");
		ResultSetMetaData rm= rs.getMetaData();
		for(int i=0;i<rm.getColumnCount();i++){
			Field field=getPropertyByColumn(rm.getColumnName(i+1));
			String fieldName=this.getFieldName(field);
			buf.append("\t<result property=\"").append(fieldName==null?"id":fieldName).append("\" column=\"").append(rm.getColumnName(i+1)).append("\" />\n");
		}
		buf.append("</resultMap>");
		System.err.println(buf.toString());
	}
	
	/**
	 * 生成insert
	 * @param rs
	 */
	private void grenerateInsertXML(ResultSet rs)throws SQLException{
		
		StringBuilder buf=new StringBuilder();
		buf.append("<insert id=\"insert").append(modelName).append("\" parameterType=\"").append(className.getName()).append("\" >\n");
		buf.append("insert into ").append(tableName).append("(FID");
		StringBuilder sql=new StringBuilder();
		sql.append("\nVALUES(#{id}");
		ResultSetMetaData rm= rs.getMetaData();
		for(int i=0;i<rm.getColumnCount();i++){
			if(rm.getColumnName(i+1).equals("FID")){
				continue;
			}
			buf.append(",").append(rm.getColumnName(i+1));
			Field field=getPropertyByColumn(rm.getColumnName(i+1));
			sql.append(",#{").append(getFieldName(field)).append(",jdbcType=").append(getJdbcType(field)).append("}");			
		}
		buf.append(")");
		sql.append(")");
		buf.append(sql);
		buf.append("\n</insert>\n");
		System.err.println(buf.toString());
	}
	/**
	 * 生成带条件的UPDATE
	 * @param rs
	 * @throws SQLException
	 */
	private void grenerateUpdateXML(ResultSet rs) throws SQLException{
		StringBuilder buf=new StringBuilder();
		buf.append("<update id=\"update").append(modelName).append("\" parameterType=\"").append(className.getName()).append("\" >\n");
		buf.append("\tupdate ").append(tableName).append("\n\t<set>\n");
		ResultSetMetaData rm= rs.getMetaData();
		for(int i=0;i<rm.getColumnCount();i++){
			if(rm.getColumnName(i+1).equals("FID")){
				continue;
			}
			Field field=getPropertyByColumn(rm.getColumnName(i+1));
			String fieldName=getFieldName(field);
			buf.append("\t\t<if test=\"").append(field==null?null:field.getName()).append("!=null and ").append(field==null?null:field.getName()).append("!=''\">");
			buf.append(rm.getColumnName(i+1)).append("=").append("#{").append(fieldName).append("},</if>\n");
		}
		buf.append("\t</set>\n");
		buf.append("where fid=#{id}");
		buf.append("\n</update>\n");
		System.err.println(buf.toString());
	}
	/**
	 * 生成DELETEBYID
	 */
	@SuppressWarnings("static-access")
	private void grenerateDeleteXml(){
		StringBuilder buf=new StringBuilder();
		buf.append("<delete id=\"delete")
			.append(modelName)
			.append("ById\" ")
			.append(" parameterType=\"string\" ")
			.append(" >\n\t");
		buf.append("delete  from ")
			.append(this.tableName)
			.append(" where fid=#{id}\n");
		buf.append("</delete>");
		System.err.println(buf.toString());
	}
	/**
	 * 生成SELECTBYID记录
	 */
	private void grenerateGetModelById(){
		StringBuilder buf=new StringBuilder();
		
		buf.append("\t")
			.append("<select id=\"get").append(modelName).append("ById\"")
			.append(" parameterType=\"string\" ")
			.append(" resultMap=\"").append(modelName).append("Result\" >")
			.append("\n");
		buf.append("\t\t")
			.append(" SELECT T.* \n\t\t\tFROM ").append(tableName)
			.append(" T where T.FID=#{id}")
			.append("\n");
		buf.append("\t</select>");
		System.err.println(buf.toString());
	}
	@SuppressWarnings("static-access")
	public void grenerateCreateTableSql(){
		StringBuilder buf=new StringBuilder();
		buf.append("create table ")
			.append(" T_").append(this.projectName).append("_").append(this.modelName);
		buf.append("(");
		buf.append("FID VARCHAR(44),\n");
		Field[] ary=className.getDeclaredFields();
		for(int i=0;i<ary.length;i++){
			Field field=ary[i];
			buf.append("\t").
			append(this.getColumnName(field)).append(" ").append(getCreateJdbcType(field)).append(",\n");
		}
		StringBuilder outBuf=new StringBuilder(buf.substring(0, buf.length()-2));
		outBuf.append(")");
		System.err.println(outBuf.toString());
	}
	private String getFieldName(Field field){
		if(field==null){
			return "";
		}else if(field.getType().toString().indexOf(".enums.")>0){
			return field.getName();
		}else if(field.getType().equals(BigDecimal.class)
				|| field.getType().equals(int.class)
				|| field.getType().equals(String.class)
				|| field.getType().equals(Integer.class)
				|| field.getType().equals(Boolean.class)
				|| field.getType().equals(boolean.class)
				|| field.getType().equals(Double.class)
				|| field.getType().equals(double.class)
				|| field.getType().equals(Date.class)
				){
			return field.getName();
		}else{
			return field.getName()+".id";
		}
	}
	
	private String getColumnName(Field field){
		if(field==null){
			return "";
		}else if(field.getType().toString().indexOf(".enums.")>0){
			return "F"+field.getName();
		}else if(field.getType().equals(BigDecimal.class)
				|| field.getType().equals(int.class)
				|| field.getType().equals(String.class)
				|| field.getType().equals(Integer.class)
				|| field.getType().equals(Boolean.class)
				|| field.getType().equals(boolean.class)
				|| field.getType().equals(Double.class)
				|| field.getType().equals(double.class)
				|| field.getType().equals(Date.class)
				){
			return "F"+field.getName();
		}else{
			return "FK"+field.getName()+"ID";
		}
	}
	
	/**
	 * 取JDBCTYPE类型
	 * @param field
	 * @return
	 */
	private String getJdbcType(Field field){
		if(field==null){
			return "VARCHAR";
		}
		String jdbcType="VARCHAR";//默认
		if(field.getType().equals(BigDecimal.class)){
			jdbcType="DOUBLE";
		}else if(field.getType().equals(Date.class)){
			jdbcType="TIMESTAMP";
		}else if(field.getType().equals(int.class) || field.getType().equals(Integer.class)){
			jdbcType="INTEGER";
		}else{
			jdbcType="VARCHAR";
		}
		return jdbcType;
	}
	
	private String getCreateJdbcType(Field field){
		if(field==null){
			return "VARCHAR2(44)";
		}
		String jdbcType="VARCHAR2(44)";//默认
		if(field.getType().equals(BigDecimal.class)){
			jdbcType="NUMBER";
		}else if(field.getType().equals(Date.class)){
			jdbcType="TIMESTAMP";
		}else if(field.getType().equals(int.class) || field.getType().equals(Integer.class)){
			jdbcType="NUMBER";
		}else{
			jdbcType="VARCHAR2(50)";
		}
		return jdbcType;
	}

	/*
	 * 取得结果集
	 */
	private ResultSet getResult(){
		Connection cn=null;
		try{
			Class.forName("oracle.jdbc.driver.OracleDriver");
			cn= DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.43:1521:ORACLE", "QFgreen1210", "QFgreen1210");
			Statement st=cn.createStatement();
			ResultSet rs=st.executeQuery("select * from "+tableName);
			return rs;
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
}
